import Food from "./Food"
import GameControl from "./GameControl"
import ScorePanel from "./ScorePanel"

// 创建Snake类
class Snake {
  // 表示蛇头
  head: HTMLElement
  // 表示蛇的身体各部
  static body: HTMLCollection
  // 包含蛇的大盒子
  element: HTMLElement
  // 食物类实例
  food: Food = new Food()
  // 得分面板实例
  scorePanel: ScorePanel = new ScorePanel(10, 2)

  constructor() {
    this.head = <HTMLElement>document.querySelector('#snake > div')
    Snake.body = (document.querySelector('#snake') as HTMLElement).children
    this.element = <HTMLElement>document.querySelector('#snake')
  }

  // 获取蛇头横坐标
  get x() {
    return this.head.offsetLeft
  }

  // 获取蛇头纵坐标
  get y() {
    return this.head.offsetTop
  }

  set x(val: number) {
    this.head.style.left = val + 'px'
  }

  set y(val: number) {
    this.head.style.top = val + 'px'
  }

  // 蛇增加身体长度的方法
  addBodyLength() {
    this.element.insertAdjacentHTML('beforeend', '<div></div>')
  }

  // 添加蛇身后的移动方法
  moveBody() {
    // 将蛇身靠前的部分赋值给蛇身靠后的部位
    for (let i = Snake.body.length - 1; i > 0; i--) {
      // // 从尾部开始遍历 获取蛇靠前一位的坐标信息
      let x = (<HTMLElement>Snake.body[i - 1]).offsetLeft;
      let y = (<HTMLElement>Snake.body[i - 1]).offsetTop;

      // 将靠前一位的坐标信息赋值给靠后一位的坐标
      (<HTMLElement>Snake.body[i]).style.left = x + 'px';
      (<HTMLElement>Snake.body[i]).style.top = y + 'px';
    }
  }

  // 蛇移动的方法
  run(moveDirection: string) {
    // 蛇越过了边界 终止游戏
    if (this.checkCrossed()) {
      GameControl.isLive = false
      return alert('Game Over!')
    }
    this.checkHeadPosition()
    this.moveBody()
    this.checkEating()
    switch (moveDirection) {
      case 'ArrowLeft':
        this.x -= 10
        break
      case 'ArrowRight':
        this.x += 10
        break
      case 'ArrowUp':
        this.y -= 10
        break
      case 'ArrowDown':
        this.y += 10
        break
    }
  }

  // 检测蛇是否吃到了食物
  checkEating() {
    // 随机生成食物位置 蛇长加1 分数加1
    if (this.x === this.food.x && this.y === this.food.y) {
      this.food.changeFoodPosition()
      this.scorePanel.addScore()
      this.addBodyLength()
    }
  }

  // 检测蛇是否撞到边界  撞到边界则停止游戏
  checkCrossed() {
    return this.x < 0 || this.x > 290 || this.y < 0 || this.y > 290
  }

  // 检查蛇头是否撞击到蛇的其他身体部位
  checkHeadPosition() {
    for (let i = 1; i < Snake.body.length; i++) {
      let bd = <HTMLElement>Snake.body[i]
      if (this.x === bd.offsetLeft && this.y === bd.offsetTop) {
        GameControl.isLive = false
        alert('Game Over!')
      }
    }
  }
}

export default Snake
